// ------------------------------------------------------------------------------------------
// Licensed by Interprise Solutions.
// http://www.InterpriseSolutions.com
// For details on this license please visit  the product homepage at the URL above.
// THE ABOVE NOTICE MUST REMAIN INTACT.
// ------------------------------------------------------------------------------------------
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Runtime.Serialization;
using InterpriseSuiteEcommerceCommon.InterpriseIntegration.JSONLib;
using InterpriseSuiteEcommerceCommon.Extensions;
using System;
using InterpriseSuiteEcommerceCommon.Tool;

namespace InterpriseSuiteEcommerceCommon.DTO
{
    [DataContractAttribute]
    public class ProductImageData
    {
        public ProductImageData(int id, string code)
        {
            this.id = id;
            this.code = code;

            InititializeImages();
        }

        public ProductImageData() 
        {
            InititializeImages();
        }

        private void InititializeImages() 
        {
            MinicartImages = new List<ProductImage>();
            MobileImages = new List<ProductImage>();
            IconImages = new List<ProductImage>();
        }

        [DataMemberAttribute]
        public int id = 0;

        [DataMemberAttribute]
        public string code = string.Empty;

        [DataMemberAttribute]
        public bool isRemote = false;

        [DataMemberAttribute]
        public ProductImage icon;

        [DataMemberAttribute]
        public ProductImage medium;

        [DataMemberAttribute]
        public ProductImage large;

        [DataMemberAttribute]
        public ProductImage swatch;

        [DataMemberAttribute]
        public ProductImage Minicart
        {
            get;
            set;
        }

        [DataMemberAttribute]
        public ProductImage Mobile
        {
            get;
            set;
        }

        [DataMemberAttribute]
        public List<ProductImage> mediumImages = new List<ProductImage>();

        [DataMemberAttribute]
        public List<ProductImage> largeImages = new List<ProductImage>();

        [DataMemberAttribute]
        public List<ProductImage> microImages = new List<ProductImage>();

        [DataMemberAttribute]
        public List<ProductImage> MinicartImages
        {
            get;
            set;
        }

        [DataMemberAttribute]
        public List<ProductImage> IconImages
        {
            get;
            set;
        }

        [DataMemberAttribute]
        public List<ProductImage> MobileImages
        {
            get;
            set;
        }

        public bool HasAnyImageInMediumMultipleImages()
        {
            foreach (ProductImage mediumImage in mediumImages)
            {
                if (mediumImage.exists) return true;
            }
            return false;
        }

        public bool HasAnyImageInMicroMultipleImages()
        {
            foreach (ProductImage microImage in microImages)
            {
                if (microImage.exists) return true;
            }

            return false;
        }

        public string Serialize()
        {
            JSONSerializer serializer = new JSONSerializer(SerializeOption.All);
            string serializationText = serializer.Serialize(this);

            return serializationText;
        }

        public string Serialize(bool newEngine)
        {
            return JSONHelper.Serialize<ProductImageData>(this);
        }

        public static void SetImageSize(ProductImage img)
        {
            if (img.exists)
            {
                Size size = CommonLogic.GetImagePixelSize(img.rel);
                img.size.width = size.Width;
                img.size.height = size.Height;

                img.rel = string.Empty;
            }
        }

        public static ProductImageData Get(int itemCounter, string itemCode, string itemType, int matrixGroupCounter)
        {
            var multiImageFileName = new List<string>();
            var multiAltTextMedium = new SortedList<string, string>();
            var multiTitleMedium = new SortedList<string, string>();
            var multiAltTextLarge = new SortedList<string, string>();
            var multiTitleLarge = new SortedList<string, string>();

            var data = new ProductImageData(itemCounter, itemCode);
            data.isRemote = AppLogic.AppConfigBool("RemoteImages.Enabled");

            //call default images here for all sizes
            var lstImages = ProductImage.LocateDefaultImageInSizes(DomainConstants.EntityProduct, itemCode);
            data.icon = lstImages.FirstOrDefault(m => m.ImageSizeType == ImageSizeTypes.icon);
            data.medium = lstImages.FirstOrDefault(m => m.ImageSizeType == ImageSizeTypes.medium);
            data.large = lstImages.FirstOrDefault(m => m.ImageSizeType == ImageSizeTypes.large);

            // set the size for the large image
            SetImageSize(data.large);

            if (!AppLogic.AppConfigBool("ImageFileNameOverride.Enabled"))
            {
                using (var con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (var reader = DB.GetRSFormat(con,
                        "SELECT e.Filename FROM InventoryOverrideImage e with (NOLOCK) WHERE e.ItemCode = {0} AND WebSiteCode = {1} AND HasMedium = 1 ORDER BY ImageIndex; " +
                        "SELECT Filename, ISNULL(SETitleMedium,'') AS SETitleMedium, ISNULL(SEAltTextMedium,'') AS SEAltTextMedium, ISNULL(SETitleLarge,'') AS SETitleLarge, ISNULL(SEAltTextLarge,'') AS SEAltTextLarge " + 
                        "FROM InventoryImageWebOptionDescription WITH (NOLOCK) " +
                        "WHERE  ItemCode = {0} AND WebSiteCode = {1} AND LanguageCode = {2}"
                        , itemCode.ToDbQuote(), InterpriseHelper.ConfigInstance.WebSiteCode.ToDbQuote(), Customer.Current.LanguageCode.ToDbQuote()))
                    {
                        while (reader.Read())
                        {
                            //use medium images as basis for multi image display
                            multiImageFileName.Add(DB.RSField(reader, "Filename").ToString());
                        }

                        reader.NextResult();

                        while (reader.Read())
                        {
                            multiAltTextMedium.Add(DB.RSField(reader, "Filename").ToString(), DB.RSField(reader, "SEAltTextMedium").ToString());
                            multiTitleMedium.Add(DB.RSField(reader, "Filename").ToString(), DB.RSField(reader, "SETitleMedium").ToString());
                            multiAltTextLarge.Add(DB.RSField(reader, "Filename").ToString(), DB.RSField(reader, "SEAltTextLarge").ToString());
                            multiTitleLarge.Add(DB.RSField(reader, "Filename").ToString(), DB.RSField(reader, "SETitleLarge").ToString());
                        }
                    }
                }
            }

            //display medium images, sync micro and large images
            for (int ctr = 0; ctr <= multiImageFileName.Count - 1; ctr++)
            {
                //not for imageoverride
                var img = ProductImage.LocateMultiImage("product", itemCode, multiImageFileName[ctr], "medium");
                img.ImgFileName = multiImageFileName[ctr];

                string alttexttitle = String.Empty;
                multiAltTextMedium.TryGetValue(multiImageFileName[ctr], out alttexttitle);
                img.Alt = alttexttitle.IsNullOrEmptyTrimmed()? String.Empty : alttexttitle.Trim().ToJavaScriptEscape();

                alttexttitle = String.Empty;
                multiTitleMedium.TryGetValue(multiImageFileName[ctr], out alttexttitle);
                img.Title = alttexttitle.IsNullOrEmptyTrimmed() ? String.Empty : alttexttitle.Trim().ToJavaScriptEscape();

                data.mediumImages.Add(img);

                var microImage = ProductImage.LocateMultiImage("product", itemCode, multiImageFileName[ctr], "micro");
                microImage.ImgFileName = multiImageFileName[ctr];
                data.microImages.Add(microImage);

                //sync display for large images, use same filename
                var largeImage = ProductImage.LocateMultiImage("product", itemCode, multiImageFileName[ctr], "large");
                SetImageSize(largeImage);

                alttexttitle = String.Empty;
                multiAltTextLarge.TryGetValue(multiImageFileName[ctr], out alttexttitle);
                largeImage.Alt = alttexttitle.IsNullOrEmptyTrimmed() ? String.Empty : alttexttitle.Trim().ToJavaScriptEscape();

                alttexttitle = String.Empty;
                multiTitleLarge.TryGetValue(multiImageFileName[ctr], out alttexttitle);
                largeImage.Title = alttexttitle.IsNullOrEmptyTrimmed() ? String.Empty : alttexttitle.Trim().ToJavaScriptEscape();

                data.largeImages.Add(largeImage);

                var iconImage = ProductImage.LocateMultiImage("product", itemCode, multiImageFileName[ctr], "icon");
                iconImage.ImgFileName = multiImageFileName[ctr];
                data.IconImages.Add(iconImage);

                var imgMinicart = ProductImage.LocateMultiImage("product", itemCode, multiImageFileName[ctr], "minicart");
                data.MinicartImages.Add(imgMinicart);

                var imgMobile = ProductImage.LocateMultiImage("product", itemCode, multiImageFileName[ctr], "mobile");
                string relativePath = AppLogic.GetMobileImagePath("product", "mobile", false);
                string absolutePath = AppLogic.GetMobileImagePath("product", "mobile", true);

                string mobileRelativePath = relativePath + multiImageFileName[ctr];
                if (System.IO.File.Exists(absolutePath + multiImageFileName[ctr]))
                {
                    imgMobile.src = mobileRelativePath;
                    imgMobile.rel = mobileRelativePath;
                    imgMobile.exists = true;
                }

                data.MobileImages.Add(imgMobile);
            }

            //dispay swatches
            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_ITEM)
            {
                data.swatch = ProductImage.Locate("product", matrixGroupCounter, "swatch", itemCounter);
            }

            if (data.medium != null)
            {
                string currentImageFilename = data.medium.ImgFileName;

                var imgMinicart = ProductImage.LocateMultiImage("product", itemCode, currentImageFilename, "minicart");
                data.Minicart = imgMinicart;

                var imgMobile = ProductImage.LocateMultiImage("product", itemCode, currentImageFilename, "mobile");
                data.Mobile = imgMobile;

                string relativePath = AppLogic.GetMobileImagePath("product", "mobile", false);
                string absolutePath = AppLogic.GetMobileImagePath("product", "mobile", true);

                string mobileRelativePath = relativePath + currentImageFilename;
                if (System.IO.File.Exists(absolutePath + currentImageFilename))
                {
                    data.Mobile.src = mobileRelativePath;
                    data.Mobile.rel = mobileRelativePath;
                    data.Mobile.exists = true;
                }

                //fix default image Alt text from the list
                var img = data.largeImages.FirstOrDefault(limg => limg.Code == data.medium.Code);
                if (img != null) { data.large.Alt = img.Alt; }

                img = data.mediumImages.FirstOrDefault(limg => limg.Code == data.medium.Code);
                if (img != null) { data.large.Alt = img.Alt; }

                img = data.microImages.FirstOrDefault(limg => limg.Code == data.icon.Code);
                if (img != null) 
                {  
                    data.icon.Alt = img.Alt;
                    data.Minicart.Alt = data.icon.Alt;
                    data.Mobile.Alt = data.icon.Alt;
                }

            }

            return data;
        }

        public static ProductImageData GetForImageUpload(int itemCounter, string itemCode, string itemType, int matrixGroupCounter)
        {
            var multiImageFileName = new List<ProductImage>();
            var multiAltTextMedium = new SortedList<string, string>();
            var multiTitleMedium = new SortedList<string, string>();
            var multiAltTextLarge = new SortedList<string, string>();
            var multiTitleLarge = new SortedList<string, string>();

            var data = new ProductImageData(itemCounter, itemCode);
            data.isRemote = AppLogic.AppConfigBool("RemoteImages.Enabled");

            //call default images here for all sizes
            var lstImages = ProductImage.LocateDefaultImageInSizesForFileUpload(DomainConstants.EntityProduct, itemCode);
            data.icon = lstImages.FirstOrDefault(m => m.ImageSizeType == ImageSizeTypes.icon);
            data.medium = lstImages.FirstOrDefault(m => m.ImageSizeType == ImageSizeTypes.medium);
            data.large = lstImages.FirstOrDefault(m => m.ImageSizeType == ImageSizeTypes.large);

            // set the size for the large image
            SetImageSize(data.large);

            if (!AppLogic.AppConfigBool("ImageFileNameOverride.Enabled"))
            {
                using (var con = DB.NewSqlConnection())
                {
                    con.Open();
                    using (var reader = DB.GetRSFormat(con ,
                        "SELECT e.Filename, IsDefaultIcon, IsDefaultMedium FROM InventoryOverrideImage e with (NOLOCK) WHERE e.ItemCode = {0} AND WebSiteCode = {1} AND (HasMedium = 1 or HasLarge = 1 or HasIcon = 1 or HasMobile = 1 or HasMinicart = 1)  ORDER BY ImageIndex; " +
                        "SELECT Filename, ISNULL(SETitleMedium,'') AS SETitleMedium, ISNULL(SEAltTextMedium,'') AS SEAltTextMedium, ISNULL(SETitleLarge,'') AS SETitleLarge, ISNULL(SEAltTextLarge,'') AS SEAltTextLarge " +
                        "FROM InventoryImageWebOptionDescription WITH (NOLOCK) " +
                        "WHERE  ItemCode = {0} AND WebSiteCode = {1} AND LanguageCode = {2}"
                            , itemCode.ToDbQuote(), InterpriseHelper.ConfigInstance.WebSiteCode.ToDbQuote(), Customer.Current.LanguageCode.ToDbQuote()))
                    {
                        while (reader.Read())
                        {
                            multiImageFileName.Add(new ProductImage(){
                                ImgFileName = DB.RSField(reader, "Filename").ToString(),
                                IsDefaultIcon = DB.RSFieldBool(reader, "IsDefaultIcon"),
                                IsDefaultMedium = DB.RSFieldBool(reader, "IsDefaultMedium")
                            });
                        }

                        reader.NextResult();

                        while (reader.Read())
                        {
                            multiAltTextMedium.Add(DB.RSField(reader, "Filename").ToString(), DB.RSField(reader, "SEAltTextMedium").ToString());
                            multiTitleMedium.Add(DB.RSField(reader, "Filename").ToString(), DB.RSField(reader, "SETitleMedium").ToString());
                            multiAltTextLarge.Add(DB.RSField(reader, "Filename").ToString(), DB.RSField(reader, "SEAltTextLarge").ToString());
                            multiTitleLarge.Add(DB.RSField(reader, "Filename").ToString(), DB.RSField(reader, "SETitleLarge").ToString());
                        }
                    }
                }
            }

            //display medium images, sync micro and large images
            for (int ctr = 0; ctr <= multiImageFileName.Count - 1; ctr++)
            {
                //not for imageoverride
                string imgFileName = multiImageFileName[ctr].ImgFileName;

                var img = ProductImage.LocateMultiImage("product", itemCode, imgFileName, "medium");
                img.ImgFileName = multiImageFileName[ctr].ImgFileName;
                img.IsDefaultMedium = multiImageFileName[ctr].IsDefaultMedium;

                string alttexttitle = String.Empty;
                multiAltTextMedium.TryGetValue(imgFileName, out alttexttitle);
                img.Alt = alttexttitle.IsNullOrEmptyTrimmed() ? String.Empty : alttexttitle.Trim().ToJavaScriptEscape();

                alttexttitle = String.Empty;
                multiTitleMedium.TryGetValue(imgFileName, out alttexttitle);
                img.Title = alttexttitle.IsNullOrEmptyTrimmed() ? String.Empty : alttexttitle.Trim().ToJavaScriptEscape();

                data.mediumImages.Add(img);

                var microImage = ProductImage.LocateMultiImage("product", itemCode, imgFileName, "micro");
                microImage.ImgFileName = imgFileName;
                data.microImages.Add(microImage);

                //sync display for large images, use same filename
                var largeImage = ProductImage.LocateMultiImage("product", itemCode, imgFileName, "large");
                SetImageSize(largeImage);

                alttexttitle = String.Empty;
                multiAltTextLarge.TryGetValue(imgFileName, out alttexttitle);
                largeImage.Alt = alttexttitle.IsNullOrEmptyTrimmed() ? String.Empty : alttexttitle.Trim().ToJavaScriptEscape();

                alttexttitle = String.Empty;
                multiTitleLarge.TryGetValue(imgFileName, out alttexttitle);
                largeImage.Title = alttexttitle.IsNullOrEmptyTrimmed() ? String.Empty : alttexttitle.Trim().ToJavaScriptEscape();

                data.largeImages.Add(largeImage);

                var iconImage = ProductImage.LocateMultiImage("product", itemCode, imgFileName, "icon");
                iconImage.ImgFileName = imgFileName;
                iconImage.IsDefaultIcon = multiImageFileName[ctr].IsDefaultIcon;
                data.IconImages.Add(iconImage);

                var imgMinicart = ProductImage.LocateMultiImage("product", itemCode, imgFileName, "minicart");
                data.MinicartImages.Add(imgMinicart);

                var imgMobile = ProductImage.LocateMultiImage("product", itemCode, imgFileName, "mobile");
                string relativePath = AppLogic.GetMobileImagePath("product", "mobile", false);
                string absolutePath = AppLogic.GetMobileImagePath("product", "mobile", true);

                string mobileRelativePath = relativePath + imgFileName;
                if (System.IO.File.Exists(absolutePath + imgFileName))
                {
                    imgMobile.src = mobileRelativePath;
                    imgMobile.rel = mobileRelativePath;
                    imgMobile.exists = true;
                }

                data.MobileImages.Add(imgMobile);
            }

            //dispay swatches
            if (itemType == Interprise.Framework.Base.Shared.Const.ITEM_TYPE_MATRIX_ITEM)
            {
                data.swatch = ProductImage.Locate("product", matrixGroupCounter, "swatch", itemCounter);
            }

            if (data.medium != null)
            {
                string currentImageFilename = data.medium.ImgFileName;

                var imgMinicart = ProductImage.LocateMultiImage("product", itemCode, currentImageFilename, "minicart");
                data.Minicart = imgMinicart;

                var imgMobile = ProductImage.LocateMultiImage("product", itemCode, currentImageFilename, "mobile");
                data.Mobile = imgMobile;

                string relativePath = AppLogic.GetMobileImagePath("product", "mobile", false);
                string absolutePath = AppLogic.GetMobileImagePath("product", "mobile", true);

                string mobileRelativePath = relativePath + currentImageFilename;
                if (System.IO.File.Exists(absolutePath + currentImageFilename))
                {
                    data.Mobile.src = mobileRelativePath;
                    data.Mobile.rel = mobileRelativePath;
                    data.Mobile.exists = true;
                }

                //fix default image Alt text from the list
                var img = data.largeImages.FirstOrDefault(limg => limg.Code == data.medium.Code);
                if (img != null) { data.large.Alt = img.Alt; }

                img = data.mediumImages.FirstOrDefault(limg => limg.Code == data.medium.Code);
                if (img != null) { data.large.Alt = img.Alt; }

                img = data.microImages.FirstOrDefault(limg => limg.Code == data.icon.Code);
                if (img != null)
                {
                    data.icon.Alt = img.Alt;
                    data.Minicart.Alt = data.icon.Alt;
                    data.Mobile.Alt = data.icon.Alt;
                }

            }

            return data;
        }

    }

    [DataContractAttribute]
    public class EntityImageHeader
    {
        [DataMemberAttribute]
        public int ID
        {
            get;
            set;
        }

        [DataMemberAttribute]
        public EntityImageDetail Thumbnail
        {
            get;
            set;
        }

        [DataMemberAttribute]
        public EntityImageDetail Medium
        {
            get;
            set;
        }

        [DataMemberAttribute]
        public EntityImageDetail Large 
        {
            get;
            set;
        }

        [DataMemberAttribute]
        public EntityImageDetail Mobile
        {
            get;
            set;
        }

        public string ToJSON() 
        {
            return JSONHelper.Serialize<EntityImageHeader>(this);
        }

    }

    [DataContractAttribute]
    public class EntityImageDetail
    {
        public EntityImageDetail()
        {
            ImgFileName = String.Empty;
            Title = String.Empty;
            Alt = String.Empty;
            exists = false;
        }

        [DataMemberAttribute]
        public string ImgFileName { get; set; }

        [DataMemberAttribute]
        public string src { get; set; }

        [DataMemberAttribute]
        public string Title { get; set; }

        [DataMemberAttribute]
        public string Alt { get; set; }

        [DataMemberAttribute]
        public bool exists { get; set; }
    }

}
